package org.zachary.imitation.raft.option;

import org.zachary.imitation.raft.Configuration;
import org.zachary.imitation.raft.JRaftServiceFactory;

import java.time.Duration;

/**
 * 初始化节点时的配置参数，也就是说，依据 {@link NodeOptions} 中定义的信息来初始化节点。节点在初始化过程中要用到哪些配置参数呢？比如说，raft 节点是通过日志复制来完成数据备份和节点状态一致的，每一条日志都需要持久化，那日志持久化的本地路径就是其中的一个配置参数。
 *
 * Created by guozhaokun on 2024/8/30 21:08.
 */
public class NodeOptions {
	/** 选举超时时间，超过这个时间没有接收到 Leader 发送的心跳信息就会触发新一轮选举，默认为 1s */
	private Duration electionTimeout = Duration.ofSeconds(1);
	/** 集群的信息 */
	private Configuration initialConf;
	/** 用来创建整个框架中要使用到的各个组件的工厂 */
	private JRaftServiceFactory serviceFactory;
	/** 当前节点的选举优先级 */
	private int electionPriority;

	/** 日志文件的本地路径 */
	private String logUri;
	/** 节点的元数据（当前处于哪个任期、当前任期当前节点将票投给了哪个节点等信息）存储文件的本地路径 */
	private String raftMetaUri;

	/** 全局定时任务管理器中线程池核心线程的数量，默认是 CPU 核数的3倍，但是不超过 20 */
	// TODO 通过系统属性获取 CPU 的核数，这里暂时写死核数为 2
	private int timerPoolSize = 2 * 3 > 20 ? 20 : 2 * 3;

	public Duration getElectionTimeout() {
		return electionTimeout;
	}

	public void setElectionTimeout(Duration electionTimeout) {
		this.electionTimeout = electionTimeout;
	}

	public Configuration getInitialConf() {
		return initialConf;
	}

	public void setInitialConf(Configuration initialConf) {
		this.initialConf = initialConf;
	}

	public String getLogUri() {
		return logUri;
	}

	public void setLogUri(String logUri) {
		this.logUri = logUri;
	}

	public String getRaftMetaUri() {
		return raftMetaUri;
	}

	public void setRaftMetaUri(String raftMetaUri) {
		this.raftMetaUri = raftMetaUri;
	}

	public JRaftServiceFactory getServiceFactory() {
		return serviceFactory;
	}

	public void setServiceFactory(JRaftServiceFactory serviceFactory) {
		this.serviceFactory = serviceFactory;
	}

	public int getElectionPriority() {
		return electionPriority;
	}

	public void setElectionPriority(int electionPriority) {
		this.electionPriority = electionPriority;
	}

	public int getTimerPoolSize() {
		return timerPoolSize;
	}

	public void setTimerPoolSize(int timerPoolSize) {
		this.timerPoolSize = timerPoolSize;
	}
}
